package configuration

import (
	"administrator/app/apputils/tokenutils"
	"administrator/app/mapper"
	"administrator/app/model"
	"database/sql"
	"errors"
	"gitee.com/aurora-engine/utils/pageutils"
	"gitee.com/aurora-engine/utils/rep"
	"gitee.com/aurora-engine/utils/treeutils"
	"gitee.com/aurora-engine/web"
	"time"
)

type OrgManagement struct {
	*mapper.UserMapper
	*mapper.OrgManageMapper
	DB *sql.DB
}

func NewOrgManagement() web.Constructor {
	return func() any {
		return &OrgManagement{}
	}
}

// OrgList
// @Description :
// @Param orgId :
// [Get] => /api/configuration/org/list/child
func (manage *OrgManagement) OrgList(args map[string]int) (rep.Response, error) {
	var err error
	var orgs []*model.Org
	if args["page"] == 0 || args["size"] == 0 {
		return rep.Fail(nil, "分页参数错误"), errors.New("分页参数错误")
	}
	limit, offset := 0, 0
	if limit, offset, err = pageutils.PageNumber(args["page"], args["size"]); err != nil {
		return rep.Fail(err, "分页参数错误"), err
	}
	args["start"], args["end"] = offset, limit
	var count int64 = 0
	if orgs, count, err = manage.GetOrgChild(args); err != nil {
		return rep.Fail(err, "查询失败"), err
	}
	page := rep.NewPage(count, orgs)
	return rep.Success(page, "查询成功"), nil
}

// GetOrg
// @Description :
// @Param orgId :
// [Get] => /api/configuration/org/list
func (manage *OrgManagement) GetOrg(orgId int) (rep.Response, error) {
	var err error
	var orgs []*model.Org
	if orgs, err = manage.AllOrg(nil); err != nil {
		return rep.Fail(err, "查询失败"), err
	}
	tree := treeutils.Tree(orgId, orgs)
	return rep.Success(tree, "查询成功"), nil
}

// GetOrgRole
// @Description :
// @Param args :
// [Get] => /api/configuration/org/role/list
func (manage *OrgManagement) GetOrgRole(args map[string]int) (rep.Response, error) {
	var err error
	var count int64
	var list []*model.Role
	if args["page"] == 0 || args["size"] == 0 {
		return rep.Fail(err, "分页信息错误"), err
	}
	limit, offset, err := pageutils.PageNumber(args["page"], args["size"])
	if err != nil {
		return rep.Fail(err, "页码解析失败"), err
	}
	args["star"], args["end"] = offset, limit
	if list, count, err = manage.GetAllRole(args); err != nil {
		return rep.Fail(err, "查询角色失败"), err
	}
	page := rep.NewPage(count, list)
	return rep.Success(page, "查询成功"), nil
}

// GetUserRoleList
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user/role
func (manage *OrgManagement) GetUserRoleList(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织不存在"), err
	}
	if _, ok := args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "用户不存在"), err
	}

	var list []*model.Role

	if list, err = manage.SelectUserRole(args); err != nil {
		return rep.Fail(err, "角色获取失败"), err
	}
	return rep.Success(list), nil
}

// GetMenuAuths
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user/roleMenuList
func (manage *OrgManagement) GetMenuAuths(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	var list []*model.MenuRouter
	if list, err = manage.SelectMenuAuth(args); err != nil {
		return rep.Fail(err, "角色权限查询失败"), err
	}
	pid := 0
	if list != nil && len(list) > 0 {
		pid = list[0].Pid
	}
	tree := treeutils.ChildTree(pid, list)
	return rep.Success(tree), nil
}

// GetFuncAuths
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user/roleFuncList
func (manage *OrgManagement) GetFuncAuths(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	var list []*model.FuncRouter
	if list, err = manage.SelectFuncAuth(args); err != nil {
		return rep.Fail(err, "角色权限查询失败"), err
	}
	return rep.Success(list), nil
}

// UserMenu
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user/menuList
func (manage *OrgManagement) UserMenu(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	if _, ok := args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}
	if _, ok := args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "用户错误"), err
	}
	var list []*model.RoleUserMenuAuth
	if list, err = manage.SelectUserMenu(args); err != nil {
		return rep.Fail(err, "授权查询失败"), err
	}

	return rep.Success(list), nil
}

// UserFunc
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user/funcList
func (manage *OrgManagement) UserFunc(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	if _, ok := args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}
	if _, ok := args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "用户错误"), err
	}
	var list []*model.RoleUserFuncAuth
	if list, err = manage.SelectUserFunc(args); err != nil {
		return rep.Fail(err, "授权查询失败"), err
	}
	return rep.Success(list), nil
}

// AddOneRole
// @Description :
// @Param args :
// [Post] => /api/configuration/org/add/role
func (manage *OrgManagement) AddOneRole(args *model.Role) (rep.Response, error) {
	var id int64
	var err error
	if _, id, err = manage.AddRole(args); err != nil {
		return rep.Fail(err, "添加角色失败"), err
	}
	args.Id = int(id)
	return rep.Success(args, "添加成功"), nil
}

// DelOneRole
// @Description :
// @Param args :
// [Post] => /api/configuration/org/del/role
func (manage *OrgManagement) DelOneRole(args map[string]int) (rep.Response, error) {
	var err error
	var id int
	// 检查 角色是否在用
	if id, err = manage.AuthExist(args); err != nil {
		return rep.Fail(err, "删除失败"), err
	}
	if id == args["id"] {
		return rep.Fail(err, "角色再用"), errors.New("删除失败")
	}
	if err = manage.Del(args); err != nil {
		return rep.Fail(err, "删除失败"), err
	}
	return rep.Success(true, "角色删除成功"), nil
}

func (manage *OrgManagement) EditRole(role *model.Role) (rep.Response, error) {

	return rep.Success(true), nil
}

// EditMenuAuth
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/edit/menu
func (manage *OrgManagement) EditMenuAuth(args map[string]any) (rep.Response, error) {
	var err error
	var ok bool
	var uid, orgId, roleId, addKeys, delKeys any
	if uid, ok = args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "授权用户错误"), err
	}
	if orgId, ok = args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}
	if roleId, ok = args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	if addKeys, ok = args["addKeys"]; !ok {
		err = errors.New("菜单授权参数错误")
		return rep.Fail(err, "添加授权参数错误"), err
	}

	if delKeys, ok = args["delKeys"]; !ok {
		err = errors.New("菜单授权参数错误")
		return rep.Fail(err, "删除授权参数错误"), err
	}
	var adds []any
	if adds, ok = addKeys.([]any); !ok {
		err = errors.New("菜单授权参数错误")
		return rep.Fail(err, "添加授权参数错误"), err
	}
	var dels []any
	if dels, ok = delKeys.([]any); !ok {
		err = errors.New("菜单授权参数错误")
		return rep.Fail(err, "删除授权参数错误"), err
	}
	menus := make([]*model.RoleUserMenuAuth, 0)
	for _, add := range adds {
		menu := &model.RoleUserMenuAuth{
			OrgId:  int(orgId.(float64)),
			UserId: int(uid.(float64)),
			RoleId: int(roleId.(float64)),
			MenuId: int(add.(float64)),
		}
		menus = append(menus, menu)
	}
	args["menus"] = menus
	begin, err := manage.DB.Begin()
	if err != nil {
		return rep.Fail(err, "授权更新失败"), err
	}
	if len(menus) > 0 {
		// 添加组织用户添加菜单授权
		if err = manage.InsertUserMenuAuth(args, begin); err != nil {
			begin.Rollback()
			return rep.Fail(err, "授权更新失败"), err
		}
	}

	if len(dels) > 0 {
		// 取消组织用户添加菜单授权
		args["dels"] = dels
		if err = manage.DeleteUserMenuAuth(args, begin); err != nil {
			begin.Rollback()
			return rep.Fail(err, "授权更新失败"), err
		}
	}
	begin.Commit()
	return rep.Success(true), nil
}

// EditFuncAuth
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/edit/func
func (manage *OrgManagement) EditFuncAuth(args map[string]any) (rep.Response, error) {
	var err error
	var ok bool
	var uid, orgId, roleId, addKeys, delKeys any
	if uid, ok = args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "授权用户错误"), err
	}
	if orgId, ok = args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}
	if roleId, ok = args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	if addKeys, ok = args["addKeys"]; !ok {
		err = errors.New("功能授权参数错误")
		return rep.Fail(err, "添加授权参数错误"), err
	}

	if delKeys, ok = args["delKeys"]; !ok {
		err = errors.New("功能授权参数错误")
		return rep.Fail(err, "删除授权参数错误"), err
	}
	var adds []any
	if adds, ok = addKeys.([]any); !ok {
		err = errors.New("功能授权参数错误")
		return rep.Fail(err, "添加授权参数错误"), err
	}
	var dels []any
	if dels, ok = delKeys.([]any); !ok {
		err = errors.New("功能授权参数错误")
		return rep.Fail(err, "删除授权参数错误"), err
	}
	funcs := make([]*model.RoleUserFuncAuth, 0)
	for _, add := range adds {
		menu := &model.RoleUserFuncAuth{
			OrgId:  int(orgId.(float64)),
			UserId: int(uid.(float64)),
			RoleId: int(roleId.(float64)),
			FuncId: int(add.(float64)),
		}
		funcs = append(funcs, menu)
	}
	args["funcs"] = funcs
	begin, err := manage.DB.Begin()
	if err != nil {
		return rep.Fail(err, "授权更新失败"), err
	}
	if len(funcs) > 0 {
		// 添加组织用户添加菜单授权
		if err = manage.InsertUserFuncAuth(args, begin); err != nil {
			begin.Rollback()
			return rep.Fail(err, "授权更新失败"), err
		}
	}

	if len(dels) > 0 {
		// 取消组织用户添加菜单授权
		args["dels"] = dels
		if err = manage.DeleteUserFuncAuth(args, begin); err != nil {
			begin.Rollback()
			return rep.Fail(err, "授权更新失败"), err
		}
	}
	begin.Commit()
	return rep.Success(true), nil
}

// AddUser
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/add
func (manage *OrgManagement) AddUser(args *model.AddUser) (rep.Response, error) {
	var err error
	var tx *sql.Tx
	if args.Id == 0 {
		return rep.Fail(nil, "选择用户"), errors.New("添加失败")
	}
	if args.Roles == nil || len(args.Roles) < 1 {
		return rep.Fail(nil, "角色不能为空"), errors.New("添加失败")
	}

	if tx, err = manage.DB.Begin(); err != nil {
		return rep.Fail(err, "添加失败"), err
	}

	v := make([]any, 0)
	for _, role := range args.Roles {
		var auth model.Authorization
		auth.UserId = args.Id
		auth.OrgId = args.OrgId
		auth.RoleId = role
		v = append(v, auth)
	}

	r := map[string]any{
		"auths":  v,
		"OrgId":  args.OrgId,
		"Id":     args.Id,
		"RoleId": args.Roles[0],
	}

	// 校验角色是否已经存在当前组织，不能二次添加
	id := 0
	if id, err = manage.OUExist(r); err != nil {
		return rep.Fail(err, "组织添加用户失败"), err
	}

	if id != 0 {
		return rep.Fail(err, "用户已存在当前组织"), errors.New("用户已存在当前组织")
	}

	// 添加组织关系
	if err = manage.SetUserOrg(r, tx); err != nil {
		tx.Rollback()
		return rep.Fail(err, "组织关系添加失败"), err
	}

	// 添加角色授权
	if err = manage.AddUserRoles(r, tx); err != nil {
		tx.Rollback()
		return rep.Fail(err, "用户权限分配失败"), err
	}

	// 设置默认组织用户和权限
	if err = manage.SetUserDefaultOR(r, tx); err != nil {
		tx.Rollback()
		return rep.Fail(err, "默认组织设置失败"), err
	}
	if err = manage.UpdateDefaultOrgRole(r, tx); err != nil {
		tx.Rollback()
		return rep.Fail(err, "默认组织设置失败"), err
	}
	tx.Commit()
	return rep.Success(true, "添加成功"), nil
}

// DelUser
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/del
func (manage *OrgManagement) DelUser(args map[string]int, token *tokenutils.Token) (rep.Response, error) {
	var err error
	// 校验数据
	if args["orgId"] == 0 || args["userId"] == 0 {
		err = errors.New("请求参数错误")
		return rep.Fail(err, "删除失败"), err
	}

	// 校验不能自己删除自己
	if args["userId"] == token.ID {
		err = errors.New("无法删除")
		return rep.Fail(err, "删除失败"), err
	}

	begin, err := manage.DB.Begin()
	if err != nil {
		return rep.Fail(err, "删除失败"), err
	}
	// 删除用户和当前组织的的组织关系
	if err = manage.OrgDelUser(args, begin); err != nil {
		begin.Rollback()
		return rep.Fail(err, "删除用户组织关系失败"), err
	}

	// 删除组织默认关系
	if err = manage.OrgDelUserDefaultInfo(args, begin); err != nil {
		begin.Rollback()
		return rep.Fail(err, "组织默认信息删除失败"), err
	}

	// 删除当前组织的角色授权
	if err = manage.OrgDelUserRoles(args, begin); err != nil {
		begin.Rollback()
		return rep.Fail(err, "删除组织授权失败"), err
	}
	// todo 删除用户对应在组织角色下的菜单,功能权限授权

	begin.Commit()
	return rep.Success(true, "删除成功"), nil
}

// AuthAddRole
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/auth/add/role
func (manage *OrgManagement) AuthAddRole(args map[string]any) (rep.Response, error) {
	var err error
	if _, ok := args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "用户错误"), err
	}
	if _, ok := args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}
	if _, ok := args["roles"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	auths := make([]*model.Authorization, 0)
	roles, ok := args["roles"].([]any)
	if !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}
	for _, role := range roles {
		auth := &model.Authorization{
			OrgId:  int(args["orgId"].(float64)),
			UserId: int(args["userId"].(float64)),
			RoleId: int(role.(float64)),
		}
		auths = append(auths, auth)
	}
	args["auths"] = auths
	if err = manage.InsertUserRole(args); err != nil {
		return rep.Fail(err, "授权失败"), err
	}
	return rep.Success(nil), nil
}

// AuthDelRole
// @Description :
// @Param args :
// [Post] => /api/configuration/org/user/auth/del/role
func (manage *OrgManagement) AuthDelRole(args map[string]int) (rep.Response, error) {
	var err error
	if _, ok := args["userId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "用户错误"), err
	}

	if _, ok := args["roleId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "角色错误"), err
	}

	if _, ok := args["orgId"]; !ok {
		err = errors.New("参数错误")
		return rep.Fail(err, "组织错误"), err
	}

	// 删除用户在组织中的授权关系
	if err = manage.DeleteUserRole(args); err != nil {
		return rep.Fail(err, "授权删除失败"), err
	}
	// todo 待添加删除用户的 菜单和功能权限

	return rep.Success(nil), nil
}

// AddOrg
// @Description :
// @Param org :
// [Post] => /api/configuration/org/create
func (manage *OrgManagement) AddOrg(org *model.Org) (rep.Response, error) {
	var err error
	if org.Pid == 0 {
		return rep.Fail(nil, "创建组织失败"), errors.New("上级组织错误")
	}
	if org.Name == "" {
		return rep.Fail(nil, "创建组织失败,组织名称不能为空"), errors.New("名称错误")
	}
	org.CreateTime = time.Now().Format(time.DateTime)
	if err = manage.CreateOrg(org); err != nil {
		return rep.Fail(nil, "组织创建失败"), err
	}
	return rep.Success(nil, "创建成功"), nil
}

// DelOrg
// @Description :
// @Param org :
// [Post] => /api/configuration/org/del
func (manage *OrgManagement) DelOrg(org *model.Org) (rep.Response, error) {
	var err error
	var id int64

	if org.Id == 0 {
		return rep.Fail(nil, "删除失败"), errors.New("组织id错误")
	}
	// 查询组织内是否存在用户
	if id, err = manage.ExistUser(org); err != nil {
		return rep.Fail(nil, "组织存在未移除用户"), err
	}
	if id != 0 {
		return rep.Fail(nil, "删除失败,组织存在未移除用户"), errors.New("组织存在未移除用户")
	}

	// 检查是否有子组织
	var ids []int
	if ids, err = manage.IsParentOrg(org); err != nil {
		return rep.Fail(err, "删除失败"), err
	}
	if ids != nil && len(ids) > 0 {
		err = errors.New("存在子组织")
		return rep.Fail(err, "删除失败"), err
	}

	//删除组织
	if err = manage.DelChildOrg(org); err != nil {
		return rep.Fail(nil, "组织删除失败"), err
	}
	return rep.Success(nil, "删除成功"), nil
}

// GetOrgUser
// @Description :
// @Param args :
// [Get] => /api/configuration/org/user
func (manage *OrgManagement) GetOrgUser(args map[string]int) (rep.Response, error) {
	var accounts []*model.Account
	var err error
	var count int64
	limit, offset := 0, 0
	if limit, offset, err = pageutils.PageNumber(args["page"], args["size"]); err != nil {
		return rep.Fail(err, "页码错误查询失败"), err
	}
	args["star"] = offset
	args["end"] = limit
	if accounts, count, err = manage.OrgUser(args); err != nil {
		return rep.Fail(err, "获取账号失败"), err
	}
	page := rep.NewPage(count, accounts)
	return rep.Success(page, "查询成功"), nil
}
